package cn.cht.service.impl;


import cn.cht.pojo.AuthCode;
import cn.cht.repository.AuthCodeRepository;
import cn.cht.service.AuthCodeService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;


@Service
public class AuthCodeServiceImpl implements AuthCodeService {
    @Autowired
    private AuthCodeRepository repository;

    @Override
    public AuthCode create(String email) {
        AuthCode code = repository.findOne((root, query, criteriaBuilder) -> criteriaBuilder.and(
                criteriaBuilder.equal(root.get("email"), email),
                criteriaBuilder.greaterThan(root.get("expireTime"),
                        Date.from(Instant.now()))
        )).orElseGet(() -> {
            AuthCode ac = new AuthCode();
            ac.setEmail(email);
            ac.setCreateTime(Date.from(Instant.now()));
            ac.setExpireTime(Date.from(Instant.now().plus(Duration.ofSeconds(30))));
            return ac;
        });
        if (StringUtils.isEmpty(code.getCode())) {
            code.setCode(String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000)));
            return repository.save(code);
        } else {
            return code;
        }
    }

    @Override
    public Integer validate(String email, String codeStr) {
        AuthCode code = new AuthCode();
        code.setCode(codeStr);
        code.setEmail(email);
        List<AuthCode> all = repository.findAll(Example.of(code),
                Sort.by(Sort.Direction.DESC, "expireTime"));
        if (all == null || all.size() == 0) {
            return 1;
        }
        AuthCode authCode = all.get(0);
        if (authCode.getExpireTime().before(Date.from(Instant.now()))) {
            return 2;
        }
        return 0;
    }
}
